package org.xmlpersist.database;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.xmlpersist.dao.DAOFactory;
import org.xmlpersist.dao.DBDao;
import org.xmlpersist.parser.XMLParser;

/***
 * 
 * DB manager delegates all database queries to dao
 */
public class DBManager {

	private Connection connection;

	private String sqlQuery;

	private XMLParser xmlParser;

	private List<Map<String, Map<String, String>>> masterList;

	private Map<String, Set<String>> tagMap;

	private String xmlFile;

	private DBDao dao;

	public DBManager(Connection connection) {
		this.connection = connection;
		setDatabaseType();
	}

	/***
	 * According to database type, specific dao will be invoked
	 */
	private void setDatabaseType() {
		try {
			String databaseName = connection.getMetaData()
					.getDatabaseProductName();
			System.out.println("databaseName" + databaseName);
			dao = DAOFactory.getDao(databaseName.toLowerCase(), connection);
			dao.setConnection(connection);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/***
	 * Calls DAO save method prior to save it checks for table existence.
	 */
	public void save() {
		checkTable();
		dao.save(constructInsertQuery());
	}

	private String constructInsertQuery() {
		StringBuilder builder = new StringBuilder();
		List<Map<String, Map<String, String>>> tags = getXmlParser()
				.getMasterList();
		Iterator<Map<String, Map<String, String>>> iterator = tags.iterator();
		while (iterator.hasNext()) {
			Map<String, Map<String, String>> subtags = iterator.next();
			for (Iterator iter = subtags.entrySet().iterator(); iter.hasNext();) {
				Map.Entry entry = (Map.Entry) iter.next();
				String tableName = entry.getKey().toString();
				builder.append("insert into " + tableName + "(");
				Map<String, String> rowtag = (Map<String, String>) entry
						.getValue();
				String columns = "";
				String values = "";
				for (Iterator rowset = rowtag.entrySet().iterator(); rowset
						.hasNext();) {
					Map.Entry rowentry = (Map.Entry) rowset.next();
					columns += rowentry.getKey().toString() + ",";
					values += "'"+rowentry.getValue().toString() + "',";
				}
				columns = columns.substring(0, columns.length() - 1);
				values = values.substring(0, values.length() - 1);
				builder.append(columns + ") values(" + values + ")#");
			}
		}

		return builder.toString();
	}

	private boolean checkTable() {
		List<String> tableList = getXmlParser().getTableList();
		Iterator<String> iter = tableList.iterator();
		while (iter.hasNext()) {
			String tableName = iter.next();
			if (!dao.hasTable(tableName)) {
				String query = constructCreateTableQuery(tableName);
				dao.createTable(query);
			}
		}
		return false;
	}

	private String constructCreateTableQuery(String tableName) {
		Set<String> column = xmlParser.getTags().get(tableName);
		StringBuilder str = new StringBuilder();
		str.append(tableName + "(");
		Iterator<String> iterator = column.iterator();
		while (iterator.hasNext()) {
			str.append(iterator.next() + " varchar(50),");
		}
		str.delete(str.length() - 1, str.length());
		str.append(")");
		return str.toString();
	}

	public XMLParser getXmlParser() {
		return xmlParser;
	}

	public void setXmlParser(XMLParser xmlParser) {
		this.xmlParser = xmlParser;
	}

}
